home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / arcers / tar316.zip / CTQUIRKS.ASM < prev    next >
Assembly Source File  |  1980-07-24  |  3KB  |  178 lines

  1.         include    farnear.inc
  2.  
  3. BIOS_timer    equ    46Ch
  4.  
  5. _DATA        segment    byte public 'DATA'
  6. cnt_suspend    dw    0,0
  7. _DATA        ends
  8.  
  9. _TEXT        segment    byte public 'CODE'
  10.         assume    cs:_TEXT, ds:_DATA
  11.     program    _suspend_value
  12. ; unsigned long suspend_value(unsigned usec)
  13.  
  14.         push    bp
  15.         mov    bp,sp
  16.         push    ds
  17.         mov    ax,_DATA
  18.         mov    ds,ax
  19.  
  20.         mov    ax,cnt_suspend
  21.         or    ax,cnt_suspend+2
  22. ; Was the initialization done?
  23.         jnz    short calculate
  24.         xor    ax,ax
  25.         mov    ds,ax
  26. ; Test the availability of BIOS timer data
  27.         xor    ah,ah
  28.         int    1Ah
  29.         cli
  30.         mov    ax,ds:BIOS_timer
  31.         mov    bx,ds:BIOS_timer+2
  32.         sti
  33. ; If the difference > 1
  34.         sub    ax,dx
  35.         sbb    bx,cx
  36.         jnz    short dummy_counter
  37.         shr    ax,1
  38.         jz    short measure
  39. ; BIOS timer data unavailable - use dummy value
  40. dummy_counter:
  41.         mov     ax,60000    ; matches α 286/8 MHz
  42.         xor    dx,dx
  43.         jmp    short store_counter
  44. ; Measure computer performance for delay calculations
  45. measure:
  46.         push    si
  47.         push    di
  48.         xor    ax,ax
  49.         mov    ds,ax
  50.         xor    dx,dx
  51.  
  52.         mov    di,ds:BIOS_timer
  53. wait_tick_over:
  54.         cmp    di,ds:BIOS_timer
  55.         je    short wait_tick_over
  56.  
  57.         add    di,6    ; wait for 5 more ticks
  58.         jmp    short loop_condition
  59. calibrate_loop:
  60.         add    ax,1
  61.         adc    dx,0    ; increase long
  62. loop_condition:
  63.         mov    cx,si    ; begin long comparison
  64.         xor    cx,ax
  65.         mov    bx,di
  66.         xor    bx,dx
  67.         or    cx,bx    ; finish long comparison
  68.         cmp    di,ds:BIOS_timer
  69.         jne    short calibrate_loop
  70. ; The result long number matches to 270272 microseconds
  71.         pop    di
  72.         pop    si
  73. store_counter:
  74.         mov    bx,_DATA
  75.         mov    ds,bx
  76.         mov    cnt_suspend,ax
  77.         mov    cnt_suspend+2,dx
  78. calculate:
  79. ; Get 48-bit multiplication
  80.         mov    ax,cnt_suspend
  81.         mul    word ptr arglist[0]    ; microseconds
  82.         mov    bx,ax
  83.         mov    cx,dx
  84.         mov    ax,cnt_suspend+2
  85.         mul    word ptr arglist[0]    ; microseconds
  86.         add    ax,cx
  87.         adc    dx,0    ; DX:AX:BX contains multiplication
  88. ; Add a half of divisor - arround the result of division
  89.         add    bx,4064
  90.         adc    ax,2
  91.         adc    dx,0
  92. ; Begin long division - shift by 4 = divide by 16
  93.         mov    cx,4
  94. shift_loop:
  95.         shr    dx,1
  96.         rcr    ax,1
  97.         rcr    bx,1
  98.         loop    short shift_loop
  99. ; Finish long division - divide by 16892
  100.         mov    cx,16892
  101.         div    cx
  102.         xchg    bx,ax
  103.         div    cx
  104.         mov    dx,bx
  105. ; DX:AX = (usec * cnt_suspend + uSEC/2) / uSEC
  106.         pop    ds
  107.         pop    bp
  108.         ret
  109. _suspend_value    endp
  110.  
  111.     program    _suspend
  112. ; void suspend(unsigned long counter)
  113.         push    bp
  114.         mov    bp,sp
  115.         push    si
  116.         push    di
  117.         push    ds
  118.         mov    si,arglist[0]    ; counter
  119.         mov    di,arglist[2]
  120.         xor    ax,ax
  121.         mov    ds,ax
  122.         xor    dx,dx
  123.         jmp    short loop_entry
  124. delay_loop:
  125.         add    ax,1
  126.         adc    dx,0    ; increase long
  127. loop_entry:
  128.         mov    cx,si    ; begin long comparison
  129.         xor    cx,ax
  130.         mov    bx,di
  131.         xor    bx,dx
  132.         cmp    di,ds:BIOS_timer
  133.         or    cx,bx    ; finish long comparison
  134.         jnz    short delay_loop
  135.  
  136.         pop    ds
  137.         pop    di
  138.         pop    si
  139.         pop    bp
  140.         ret
  141. _suspend    endp
  142.  
  143.     program    _ptr2abs
  144. ; long ptr2abs(void far *ptr)
  145.         push    bp
  146.         mov    bp,sp
  147.         mov    ax,arglist[0]    ; offset
  148.         mov    bx,arglist[2]    ; segment
  149.         mov    cl,4
  150.         mov    dx,bx
  151.         shl    bx,cl
  152.         rol    dx,cl
  153.         xor    dx,bx    ; clear all save page number
  154.         add    ax,bx    ; AX = page offset
  155.         adc    dx,0    ; DX = page number
  156.         pop    bp
  157.         ret
  158. _ptr2abs    endp
  159.  
  160.     program    _timer
  161. ; unsigned long timer(void) - read PC internal timer
  162.         xor    ah,ah
  163.         int    1Ah
  164.         mov    ax,dx
  165.         mov     dx,cx
  166.  
  167. ;        push    ds
  168. ;        xor    ax,ax
  169. ;        mov    ds,ax
  170. ;        lds    ax,ds:BIOS_timer
  171. ;        mov    dx,ds
  172. ;        pop    ds
  173.         ret
  174. _timer        endp
  175.  
  176. _TEXT        ends
  177.         end
  178.